package com.hnas.api.server;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.hnas.activity.orm.Activity;
import com.hnas.api.domain.DataType;
import com.hnas.api.domain.ResultCode;
import com.hnas.api.domain.RouteFinalValue;
import com.hnas.api.dto.CommonKeyData;
import com.hnas.api.dto.DTOApiResponse;
import com.hnas.api.dto.DTORequest;
import com.hnas.api.dto.DTOResult;
import com.hnas.api.dto.PostKey;
import com.hnas.api.util.AESTool;
import com.hnas.api.util.CommonUtil;
import com.hnas.api.util.HttpRequest;
import com.hnas.api.util.SignatureUtil;
import com.hnas.api.util.StringUtil;
import com.hnas.eCard.intf.CoreSaleCardOut;
import com.hnas.trade.dto.intf.LinkNetTradeIn;

@Component("postConnServerNew")
public class PostConnServer {
	
	private static Log logger = LogFactory.getLog(PostConnServer.class);
	
	@Value(value = "#{component['postUrl.website']}")
	private String website = "http://202.100.241.142:8086/AppSys/api/index";

	private static ObjectMapper objectMapper = new ObjectMapper();

	@Autowired
	private CommonKeyData ckd;

	@Autowired
	private InitApp initApp;

	AESTool aes = new AESTool();

	SignatureUtil signatureUtil = new SignatureUtil();
	
	public <T> T getResultDataThrowException(Object object, String toroute, Class<T> clz) throws Exception{
		T t = null;
		DTOApiResponse dtoResponse = this.getRequestData(object, toroute);
		if(null != dtoResponse) {
		    DTOResult dtoResult = dtoResponse.getResult();
		    String resultcode = dtoResult.getResultCode();
		    if(ResultCode.SUCCESS.equals(resultcode)){
		    	t = clz.newInstance();
		    	String resultData = dtoResult.getResultData();
			    if(StringUtil.isNotEmpty(resultData)){
			    	resultData = aes.decrypt(resultData, dtoResponse.getKey());// 解密
					if(StringUtil.isNotEmpty(resultData)||!"nan".equals(resultData.toLowerCase())){
						t = objectMapper.readValue(resultData, clz);
					}
			    }
		    }else if(ResultCode.ERRCODE_50027.equals(resultcode)){
		    	t = clz.newInstance();
		    }
		}
		return t;
	}
	
	@SuppressWarnings({ "finally" })
	public <T> T getResultData(Object object, String toroute, Class<T> clz) {
		T t = null;
		try {
			DTOApiResponse dtoResponse = this.getRequestData(object, toroute);
			if(null != dtoResponse) {
			    DTOResult dtoResult = dtoResponse.getResult();
			    String resultcode = dtoResult.getResultCode();
			    if(ResultCode.SUCCESS.equals(resultcode)){
			    	t = clz.newInstance();
			    	String resultData = dtoResult.getResultData();
				    if(StringUtil.isNotEmpty(resultData)){
				    	resultData = aes.decrypt(resultData, dtoResponse.getKey());// 解密
						if(StringUtil.isNotEmpty(resultData)||!"nan".equals(resultData.toLowerCase())){
							t = objectMapper.readValue(resultData, clz);
						}
				    }
			    }else if(ResultCode.ERRCODE_50027.equals(resultcode)){
			    	t = clz.newInstance();
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
			t = null;
		} finally {
			return t;
		}
	}
	
	@SuppressWarnings({ "finally" })
	public <T> List<T> getListResultData(Object object, String toroute, Class<T> clz) {
		List<T> list = null;
		try {
			DTOApiResponse dtoResponse = this.getRequestData(object, toroute);
			if(null != dtoResponse) {
			    DTOResult dtoResult = dtoResponse.getResult();
			    String resultcode = dtoResult.getResultCode();
			    if(ResultCode.SUCCESS.equals(resultcode)){
			    	list = new ArrayList<T>();
			    	String resultData = dtoResult.getResultData();
				    if(StringUtil.isNotEmpty(resultData)){
				    	resultData = aes.decrypt(resultData, dtoResponse.getKey());// 解密
						if(StringUtil.isNotEmpty(resultData)||!"nan".equals(resultData.toLowerCase())){
							JavaType javaType = CommonUtil.getCollectionType(ArrayList.class, clz);
							list = objectMapper.readValue(resultData, javaType);
						}
				    }
			    }else if(ResultCode.ERRCODE_50027.equals(resultcode)){
			    	list = new ArrayList<T>();
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
			list = null;
		} finally {
			return list;
		}
	}
	
	public DTOApiResponse getRequestData(Object object, String toroute) throws Exception {
		DTOApiResponse dtoResponse = null;
		PostKey postKey = initApp.initApp(website);
		try {

			String appid = ckd.getAppid();// 公司标识
			String token = postKey.getToken();// 令牌
			String route = toroute;// 路由名称
			String key = postKey.getKey();// 加密key
			String termNo = ckd.getTermNo();// 设备编号，唯一

			// 请求参数
			DTORequest dtoRequest = new DTORequest();
			dtoRequest.setAppid(appid);// APP标识
			long millis = System.currentTimeMillis();
			dtoRequest.setMillis(millis);// 时间戳
			String version = "1.0.0";
			dtoRequest.setVersion(version);// 接口版本
			dtoRequest.setRoute(route);// 路由名称
			dtoRequest.setToken(token);// 令牌
			dtoRequest.setTermNo(termNo);
			// 加密发送数据
			String sdatajson;
			sdatajson = objectMapper.writeValueAsString(object);
			// 实体转json
			String sdata = "";
			// System.out.println("加密前的数据是:" + sdatajson);
			// System.out.println("密钥key:" + key);
			if (!sdatajson.equals("") && sdatajson != null && !sdatajson.equals("null") && !sdatajson.equals(null) && !key.equals("")) {
				sdata = aes.encrypt(sdatajson, key);// 加密
			}
			// 发送数据赋值
			dtoRequest.setSdata(sdata);
			String lol = "";// 摘要
			String sign = signatureUtil.generateSignature(appid, token, lol, millis);// 签名
			dtoRequest.setSign(sign);
			// 请求实体转json
			String requestJson = objectMapper.writeValueAsString(dtoRequest);// 实体转json
			// pos数据
			// 发送 POST 请求
			StringBuffer param = new StringBuffer();
			param.append("dataType=" + DataType.JSON);
			if (StringUtil.isNotEmpty(requestJson)) {
				requestJson = URLEncoder.encode(requestJson, "UTF-8");
			}
			param.append("&sendData=" + requestJson);
			// System.out.println("请求参数:" + param.toString());
			// 发送数据
			String requestData = HttpRequest.sendPost(website, param.toString());
			// System.out.println("请求返回:" + requestData);

			if (null != requestData) {
				dtoResponse = objectMapper.readValue(requestData, DTOApiResponse.class);
				dtoResponse.setKey(key);
			}
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return dtoResponse;
	}
	
	/**
	 * 调用的方法是否需要加解密
	 * @param object
	 * @param toroute
	 * @param isEncrypt [true:加密,false:不加密]
	 * @return
	 * @throws Exception
	 */
	public DTOApiResponse getRequestData(Object object, String toroute, boolean isEncrypt) throws Exception {
		DTOApiResponse dtoResponse = null;
		PostKey postKey = initApp.initApp(website);
		try {

			String appid = ckd.getAppid();// 公司标识
			String token = postKey.getToken();// 令牌
			String route = toroute;// 路由名称
			String key = postKey.getKey();// 加密key
			String termNo = ckd.getTermNo();// 设备编号，唯一

			// 请求参数
			DTORequest dtoRequest = new DTORequest();
			dtoRequest.setAppid(appid);// APP标识
			long millis = System.currentTimeMillis();
			dtoRequest.setMillis(millis);// 时间戳
			String version = "1.0.0";
			dtoRequest.setVersion(version);// 接口版本
			dtoRequest.setRoute(route);// 路由名称
			dtoRequest.setToken(token);// 令牌
			dtoRequest.setTermNo(termNo);
			// 加密发送数据
			String sdatajson;
			sdatajson = objectMapper.writeValueAsString(object);
			// 实体转json
			String sdata = "";
			if(isEncrypt){ // 加密
				if (!sdatajson.equals("") && sdatajson != null && !sdatajson.equals("null") && !sdatajson.equals(null) && !key.equals("")) {
					sdata = aes.encrypt(sdatajson, key);// 加密
				}
			}else{ // 不加密
				sdata = sdatajson;
			}
			// 发送数据赋值
			dtoRequest.setSdata(sdata);
			String lol = "";// 摘要
			String sign = signatureUtil.generateSignature(appid, token, lol, millis);// 签名
			dtoRequest.setSign(sign);
			// 请求实体转json
			String requestJson = objectMapper.writeValueAsString(dtoRequest);// 实体转json
			// pos数据
			// 发送 POST 请求
			StringBuffer param = new StringBuffer();
			param.append("dataType=" + DataType.JSON);
			if (StringUtil.isNotEmpty(requestJson)) {
				requestJson = URLEncoder.encode(requestJson, "UTF-8");
			}
			param.append("&sendData=" + requestJson);
			// 发送数据
			String requestData = HttpRequest.sendPost(website, param.toString());

			if (null != requestData) {
				dtoResponse = objectMapper.readValue(requestData, DTOApiResponse.class);
				dtoResponse.setKey(key);
			}
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return dtoResponse;
	}
	
	@SuppressWarnings({ "finally" })
	public Activity getActivity(String mrchId,String termNo,String subCode) {
		JSONObject jo = new JSONObject();
		jo.put("mrchId", mrchId);
		jo.put("termNo", termNo);
		jo.put("subCode", subCode);
		Activity t = null;
		try {
			DTOApiResponse dtoResponse = this.getRequestData(jo, RouteFinalValue.Activity_GetValidActivitieInfo);
			if(null != dtoResponse) {
			    DTOResult dtoResult = dtoResponse.getResult();
			    String resultcode = dtoResult.getResultCode();
			    if(ResultCode.SUCCESS.equals(resultcode)||ResultCode.ERRCODE_50027.equals(resultcode)){
			    	t = new Activity();
			    	String resultData = dtoResult.getResultData();
				    if(StringUtil.isNotEmpty(resultData)){
				    	resultData = aes.decrypt(resultData, dtoResponse.getKey());// 解密
						if(StringUtil.isNotEmpty(resultData)||!"nan".equals(resultData.toLowerCase())){
							t = objectMapper.readValue(resultData, Activity.class);
						}
				    }
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
			t = null;
		} finally {
			return t;
		}
	}
	
	public DTOResult linkNetTradeNew(LinkNetTradeIn object){
		try {
			DTOApiResponse dtoResponse = this.getRequestData(object, RouteFinalValue.APP_LinkNetTradeNew);
			DTOResult dtoResult = null;
			if(null != dtoResponse) {
			    dtoResult = dtoResponse.getResult();
			    String resultcode = dtoResult.getResultCode();
			    if(ResultCode.SUCCESS.equals(resultcode)){
			    	String resultData = dtoResult.getResultData();
				    if(StringUtil.isNotEmpty(resultData)){
				    	resultData = aes.decrypt(resultData, dtoResponse.getKey());// 解密
						if(StringUtil.isNotEmpty(resultData)||!"nan".equals(resultData.toLowerCase())){
							dtoResult.setResultData(resultData);
						}
				    }
			    }
			}
			return dtoResult;
		} catch (Exception e) {//调用接口异常
			e.printStackTrace();
			return null;
		}
	}
	
	public CoreSaleCardOut sellECards(String orderNo,Integer cardNum, Long denomination, String merchantId, String cardType,String swiftNumber,String payChannel) {
		JSONObject jo = new JSONObject();
		jo.put("orderNo", orderNo);
		jo.put("merchantId", merchantId);
		jo.put("cardKind", cardType);
		jo.put("cardNum", cardNum);
		jo.put("rechargeAmt", denomination);
		jo.put("swiftNumber", swiftNumber);
		jo.put("rechargeChannel", payChannel);
		CoreSaleCardOut t = null;
		try {
			DTOApiResponse dtoResponse = this.getRequestData(jo,"APP_WXXNK_ECARD_SaleECards");
			if(null != dtoResponse) {
			    DTOResult dtoResult = dtoResponse.getResult();
			    String resultcode = dtoResult.getResultCode();
			    if(ResultCode.SUCCESS.equals(resultcode)){
			    	t = new CoreSaleCardOut();
			    	String resultData = dtoResult.getResultData();
				    if(StringUtil.isNotEmpty(resultData)){
				    	resultData = aes.decrypt(resultData, dtoResponse.getKey());// 解密
						if(StringUtil.isNotEmpty(resultData)||!"nan".equals(resultData.toLowerCase())){
							t = objectMapper.readValue(resultData, CoreSaleCardOut.class);
						}
				    }
			    }else if(ResultCode.ERRCODE_50027.equals(resultcode)) {
			    	t = new CoreSaleCardOut();
			    }
			    return t;
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
}
